package com.chuangjiangx.member.manager.client.web.basic.controller;

import com.chuangjiangx.commons.BeanUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.commons.response.CamelResponse;
import com.chuangjiangx.commons.response.Response;
import com.chuangjiangx.commons.response.ResponseUtils;
import com.chuangjiangx.commons.sms.SMSUtils;
import com.chuangjiangx.member.basic.ddd.application.MbrSmsApplication;
import com.chuangjiangx.member.basic.ddd.application.MemberApplication;
import com.chuangjiangx.member.basic.ddd.application.command.ModifyMemberCommand;
import com.chuangjiangx.member.basic.ddd.application.command.ModifyMobileCommand;
import com.chuangjiangx.member.basic.ddd.application.command.RegisterMemberCommand;
import com.chuangjiangx.member.basic.ddd.dal.dto.MbrAccountDTO;
import com.chuangjiangx.member.basic.ddd.query.MbrAccountQuery;
import com.chuangjiangx.member.basic.ddd.query.MemberQuery;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberCondition;
import com.chuangjiangx.member.basic.ddd.query.condition.SearchMemberInfoCondition;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberDetailDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberListDTO;
import com.chuangjiangx.member.coupon.ddd.application.command.CancelMemberCommand;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.interceptor.Login;
import com.chuangjiangx.member.manager.basic.web.interceptor.Permissions;
import com.chuangjiangx.member.manager.client.web.basic.request.*;
import com.chuangjiangx.member.manager.client.web.basic.response.MemberDetailResponse;
import com.chuangjiangx.member.manager.client.web.basic.response.NewMemberInfoResponse;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.member.manager.common.ThreadLocalUser;
import com.chuangjiangx.member.manager.common.utils.StrUtils;
import com.sun.jmx.snmp.ThreadContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * 会员管理--全部角色
 */
@Api(value = "会员管理--全部角色",tags = "会员")
@RestController
@Log
@RequestMapping(value = "/app/member", produces = "application/json")
public class MemberClientController extends BaseController {


    @Autowired
    private  MemberApplication memberApplication;
    @Autowired
    private  MemberQuery memberQuery;
    @Autowired
    private  StringRedisTemplate redisTemplate;
    @Autowired
    private MbrSmsApplication mbrSmsApplication;
    @Autowired
    private MbrAccountQuery mbrAccountQuery;

    /**
     * 校验当前手机号是否为会员
     *
     * @param checkPhone 手机号码
     * @return 校验结果
     */
    @ApiOperation(value = "校验当前手机号是否为会员")
    @RequestMapping(value = "/checkMember",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59005")
    public Response checkMemberByPhone(@Validated @RequestBody CheckPhone checkPhone, HttpServletRequest request) throws Exception {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        MemberDTO memberDTO = memberQuery.queryByMerchantAndMobile(user.getMerchantId(), checkPhone.getPhone());
        if (memberDTO == null) {
            return ResponseUtils.error("9999", "该手机号未注册会员");
        }
        return ResponseUtils.success(true);
    }


    /**
     * 注册会员
     *
     * @param createMember 会员信息
     * @return 注册结果
     */
    @ApiOperation(value = "注册会员")
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59000")
    public Response memberRegister(@Validated @Valid @RequestBody CreateMemberRequest createMember, @ApiIgnore HttpServletRequest request) throws Exception {

        // 校验短信验证码是否正确
        SMSUtils.codeCheck(createMember.getMobile(), createMember.getVerifyCode(), redisTemplate);
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        SearchMemberInfoCondition condition = new SearchMemberInfoCondition();
        condition.setMobile(createMember.getMobile());
        condition.setMerchantId(user.getMerchantId());
        //查询操作
        MemberDetailDTO detailDTO = memberQuery.searchMemberDetailByMobile(condition);
        if (detailDTO == null) {
            //判断终端类型，用于转换
            //会员信息
            RegisterMemberCommand command = new RegisterMemberCommand(
                    createMember.getName(),
                    createMember.getSex(),
                    createMember.getMobile(),
                    null,
                    createMember.getBirthday(),
                    user.getMerchantId(),
                    user.getStoreId(),
                    user.getStoreUserId(),
                    user.getTerminalType(),
                    user.getTerminalNum(),
                    user.getMerchantUserId(),
                    null,
                    null,
                    null
            );
            memberApplication.clientRegisterMember(command);
        } else {
            throw new Exception("当前手机号码已经注册过会员！");
        }
        return ResponseUtils.success();
    }

    /**
     * 修改会员信息
     *
     * @param updateMember 会员信息
     * @return 修改结果
     */
    @ApiOperation(value = "修改会员信息")
    @RequestMapping(value = "/updateMember",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59001")
    public Response updateMember(@Validated @RequestBody UpdateMemberRequest updateMember, HttpServletRequest request) throws Exception {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        //更新的会员信息
        ModifyMemberCommand modifyMemberCommand = new ModifyMemberCommand(
                updateMember.getId(),
                updateMember.getName(),
                updateMember.getSex(),
                updateMember.getBirthday(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                user.getTerminalType(),
                user.getTerminalNum(),
                null,
                user.getMerchantUserId()
        );

        //更新操作
        memberApplication.modifyMember(modifyMemberCommand);
        return ResponseUtils.success();
    }

    /**
     * 修改会员手机号码
     *
     * @param updatePhoneRequest 请求参数
     * @return 修改结果
     */
    @RequestMapping(value = "/updateMemberPhone",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59002")
    @ApiOperation(value = "修改会员手机号码")
    public Response updatePhoneNumber(@Validated @RequestBody UpdatePhoneRequest updatePhoneRequest, HttpServletRequest request) throws Exception {

        // 校验短信验证码是否正确
        SMSUtils.codeCheck(updatePhoneRequest.getMobile(), updatePhoneRequest.getVerifyCode(), redisTemplate);
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        //修改的会员手机号码信息
        ModifyMobileCommand modifyMobileCommand = new ModifyMobileCommand(
                updatePhoneRequest.getMemberId(),
                updatePhoneRequest.getMobile(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                user.getTerminalType(),
                user.getTerminalNum(),
                user.getMerchantUserId()
        );
        memberApplication.modifyMobile(modifyMobileCommand);
        return ResponseUtils.success();
    }

    /**
     * 根据会员手机号码，查询会员信息
     *
     * @param checkPhone 手机号码
     * @return 查询结果
     */
    @RequestMapping(value = "/searchMemberInfo",method =RequestMethod.POST )
    @ResponseBody
    @Login
    @Permissions("59003")
    @ApiOperation(value = "根据会员手机号码，查询会员信息" )
    public Response searchMemberByPhone(@Validated @RequestBody CheckPhone checkPhone,@ApiIgnore HttpServletRequest request) throws Exception {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        NewMemberInfoResponse memberInfo = new NewMemberInfoResponse();
        SearchMemberInfoCondition condition = new SearchMemberInfoCondition();
        condition.setMobile(checkPhone.getPhone());
        condition.setMerchantId(user.getMerchantId());

        //查询操作
        MemberDetailDTO detailDTO = memberQuery.searchMemberDetailByMobile(condition);
        Assert.notNull(detailDTO, "该手机号不是会员！");

        //对象转换
        memberInfo.setId(detailDTO.getMemberId());
        BeanUtils.convertBean(detailDTO, memberInfo);
        MbrAccountDTO accountDTO = mbrAccountQuery.queryBymemberId(detailDTO.getMemberId());
        memberInfo.setLastUpdateTime(accountDTO.getUpdateTime());
        return ResponseUtils.success("memberInfo", memberInfo);

    }

    /**
     * 根据会员id删除会员信息
     *
     * @param params 会员id
     * @return
     */
    @ApiOperation(value = "根据会员id删除会员信息" )
    @RequestMapping(value = "/deleteMember",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59009")
    public Response disableMember(HttpServletRequest request, @Validated @RequestBody DeleteMemberRequest params) throws Exception {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        String version = request.getHeader("version");

        //注销会员时必要参数
        CancelMemberCommand cancelMemberCommand = new CancelMemberCommand(
                params.getMemberId(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                user.getTerminalType(),
                user.getTerminalNum(),
                user.getMerchantUserId()
        );
        //老版本
        if (StringUtils.isBlank(version)) {
            memberApplication.cancelMember(cancelMemberCommand);
        } else {
            memberApplication.cancelMember(cancelMemberCommand);
        }
        return ResponseUtils.success();
    }


    /**
     * 根据手机号码，发送验证码
     *
     * @param checkPhone 手机号码
     * @return 发送结果
     */
    @ApiOperation(value = "根据手机号码，发送验证码")
    @RequestMapping(value = "/send-code",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59004")
    public Response sendMobleCode(@Validated @RequestBody CheckPhone checkPhone) throws Exception {
//        String code = SMSUtils.sendCodeInfo(checkPhone.getPhone(), redisTemplate);
//        CodeMsg codeMsg = new CodeMsg(code);
//        //推送模板
//        redisService.pushRongLianSMS(checkPhone.getPhone(), 2, codeMsg, code);
//        //保存验证码到redis
//        SMSUtils.saveCodeInfo(checkPhone.getPhone(), code, redisTemplate);
        mbrSmsApplication.sendMobileVerifyCode(checkPhone.getPhone());
        return ResponseUtils.success();
    }


    /**
     * 根据手机号码，发送验证码(用于登录)
     *
     * @param sendCodeRequest 手机号码,商户id
     * @return 发送结果
     */
    @ApiOperation(value = "根据手机号码，发送验证码(用于登录)")
    @RequestMapping(value = "/send-code-login",method = RequestMethod.POST)
    @ResponseBody
    @Login
    @Permissions("59010")
    public Response sendMobleCode(@Validated @RequestBody SendCodeRequest sendCodeRequest) throws Exception {

        //查询用户信息，用于校验当前手机号码是否为会员
        SearchMemberInfoCondition condition = new SearchMemberInfoCondition();
        condition.setMobile(sendCodeRequest.getPhone());
        condition.setMerchantId(sendCodeRequest.getMerchantId());
        MemberDetailDTO detailDTO = new MemberDetailDTO();
        Assert.notNull(detailDTO, "该手机号码未注册会员");

        //发送验证码
        mbrSmsApplication.sendMobileVerifyCode(sendCodeRequest.getPhone());
//        String code = SMSUtils.sendCodeInfo(sendCodeRequest.getPhone(), redisTemplate);
//        CodeMsg codeMsg = new CodeMsg(code);
//        //推送模板
//        redisService.pushRongLianSMS(sendCodeRequest.getPhone(), 2, codeMsg, code);
//        //保存验证码到redis
//        SMSUtils.saveCodeInfo(sendCodeRequest.getPhone(), code, redisTemplate);
        return ResponseUtils.success();
    }


    /**
     * 会员列表查询
     */
    @ApiOperation(value = "会员列表查询")
    @RequestMapping(value = "/member-list",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    @Login
    public CamelResponse<PagingResult<MemberListDTO>> memberList(@Validated MemberListRequest memberListRequest) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        MemberCondition condition = new MemberCondition();
        BeanUtils.convertBean(memberListRequest,condition);
        condition.setMerchantId(user.getMerchantId());
        PagingResult<MemberListDTO> pagingResult = memberQuery.queryMemberList(condition);
        pagingResult.getItems().forEach(member -> {
            member.setMobile(StrUtils.encodeMobilePhone(member.getMobile()));
        });
        return (CamelResponse<PagingResult<MemberListDTO>>)ResponseUtils.successCamel(pagingResult);
    }


    /**
     * 会员详情查询
     */
    @ApiOperation(value = "会员详情查询")
    @RequestMapping(value = "/member-detail",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    @Login
    public CamelResponse<MemberDetailResponse> memberDetail(@Validated MemberDetailRequest memberListRequest) {
        MemberDetailResponse memberDetailResponse = new MemberDetailResponse();
        MemberDetailDTO  memberDetailDTO = memberQuery.searchMemberDetailById(Long.valueOf(memberListRequest.getId()));
        BeanUtils.convertBean(memberDetailDTO,memberDetailResponse);
        memberDetailResponse.setAvailableCouponCount(memberDetailDTO.getAvailableCouponAmount());
        memberDetailResponse.setMobile(StrUtils.encodeMobilePhone(memberDetailResponse.getMobile()));
        return (CamelResponse<MemberDetailResponse>)ResponseUtils.successCamel(memberDetailResponse);
    }

}
